package com.ujcms.cms.ext.web.backendapi;

import static com.ujcms.cms.core.support.Constants.validPage;
import static com.ujcms.cms.core.support.Constants.validPageSize;
import static com.ujcms.cms.core.support.UrlConstants.BACKEND_API;
import static com.ujcms.commons.db.MyBatis.springPage;
import static com.ujcms.commons.query.QueryUtils.getQueryMap;

import com.ujcms.cms.core.aop.annotations.OperationLog;
import com.ujcms.cms.core.aop.enums.OperationType;
import com.ujcms.cms.ext.domain.Company;
import com.ujcms.cms.ext.service.CompanyService;
import com.ujcms.cms.ext.service.args.CompanyArgs;
import com.ujcms.commons.web.Entities;
import com.ujcms.commons.web.Responses.Body;
import com.ujcms.commons.web.Responses;
import com.ujcms.commons.web.exception.Http400Exception;
import com.ujcms.commons.web.exception.Http404Exception;

import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

@RestController("backendCompanyController")
@RequestMapping(BACKEND_API + "/ext/company")
public class CompanyController {
    private final CompanyService service;

    public CompanyController(CompanyService service) {
        this.service = service;
    }

    @GetMapping
    @PreAuthorize("hasAnyAuthority('company:list','*')")
    public Page<Company> list(@RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize, HttpServletRequest request) {
        CompanyArgs args = CompanyArgs.of(getQueryMap(request.getQueryString()));
        return springPage(service.selectPage(args, validPage(page), validPageSize(pageSize)));
    }

    @GetMapping("{id}")
    @PreAuthorize("hasAnyAuthority('company:show','*')")
    public Company show(@PathVariable("id") Long id) {
        return Optional.ofNullable(service.select(id))
                .orElseThrow(() -> new Http404Exception(Company.NOT_FOUND + id));
    }

    @PostMapping
    @PreAuthorize("hasAnyAuthority('company:create','*')")
    @OperationLog(module = "company", operation = "create", type = OperationType.CREATE)
    public ResponseEntity<Body> create(@RequestBody @Valid Company bean) {
        Company company = new Company();
        Entities.copy(bean, company);
        service.insert(company);
        return Responses.ok();
    }

    @PutMapping
    @PreAuthorize("hasAnyAuthority('company:update','*')")
    @OperationLog(module = "company", operation = "update", type = OperationType.UPDATE)
    public ResponseEntity<Body> update(@RequestBody @Valid Company bean) {
        Company company = Optional.ofNullable(service.select(bean.getId()))
                .orElseThrow(() -> new Http400Exception(Company.NOT_FOUND + bean.getId()));
        Entities.copy(bean, company);
        service.update(company);
        return Responses.ok();
    }

    @DeleteMapping
    @PreAuthorize("hasAnyAuthority('company:delete','*')")
    @OperationLog(module = "company", operation = "delete", type = OperationType.DELETE)
    public ResponseEntity<Body> delete(@RequestBody List<Long> ids) {
        for (Long id : ids) {
            Company bean = Optional.ofNullable(service.select(id))
                    .orElseThrow(() -> new Http400Exception(Company.NOT_FOUND + id));
            service.delete(bean.getId());
        }
        return Responses.ok();
    }
}